package galaxies.sectors;

import java.awt.Polygon;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import utilities.CoordConvert;
import utilities.MVCMaker;
import view.EViewList;
import view.AbstractView;

import com.jme3.asset.AssetManager;
import com.jme3.math.Vector2f;

import controller.AbstractController;
import controller.IController;
import eventManager.EventManager;
import galaxies.starRegions.StarRegionModel;

public class SectorBuilder {
	
	private static final Logger logger = Logger.getLogger(SectorBuilder.class.getName());
	
	public HashMap<Integer, ArrayList<Integer>> remainingLocations;
	public ArrayList<Integer> offset = new ArrayList<Integer>();
	public ArrayList<ArrayList<Integer>> chosenLocations = new ArrayList<ArrayList<Integer>>();
	
	public SectorBuilder(HashMap<Integer, ArrayList<Integer>> locations, ArrayList<Integer> offset) {
		this.remainingLocations = locations;
		this.offset.clear();
		this.offset.addAll(offset);		
	}
	
	public ArrayList<IController> buildSectors(
			ArrayList<StarRegionModel> starRegions,
			AssetManager assetManager) {
		
		logger.log(Level.INFO, "Build sectors");
		ArrayList<IController> controllers;
		HashMap<String, ArrayList<ArrayList<Integer>>> starLocations = new HashMap<String, ArrayList<ArrayList<Integer>>>();
		
		for (Integer i = 0; i < starRegions.size(); i++) { //+1 to account for center region, not returned from factory above			
			starLocations.put("SECTOR" + i.toString(), new ArrayList<ArrayList<Integer>>());			
		}
		
		logger.log(Level.INFO, "Building sector polys");
		ArrayList<Polygon> polys = new ArrayList<Polygon>();
		logger.log(Level.INFO, "NumStarRegions = " + starRegions.size());
		for (StarRegionModel region: starRegions) {
			ArrayList<Vector2f> points = region.getPoints();
			
			Polygon poly = new Polygon();
			
			for (Integer i = 0; i < points.size(); i++) {
				Vector2f vec = points.get(i);
				poly.addPoint((int)vec.x, (int)vec.y);
			}
			
			polys.add(poly);			
		}
		logger.log(Level.INFO, "Finished building sector polys");
		logger.log(Level.INFO, "Sector polygons = " + polys.size());
		
		int u, v, w;
		ArrayList<Double> cartesians;
		double x,y;
		float dist;
		int k =0;
		Integer j;
		String tempName;
		
		logger.log(Level.INFO, "Sector locations to assign = " + remainingLocations.size());
		
		for (Map.Entry<Integer, ArrayList<Integer>> entry : remainingLocations.entrySet()) {
			ArrayList<Integer> location = entry.getValue();
			Integer index = entry.getKey();
			
			k++;
			if (k%10000==0) {
				System.out.println(k + " of " + remainingLocations.size() + "locations assigned");				
			}
			
			u = location.get(0); //tile.getU();
			v = location.get(1); //tile.getV();
			w = location.get(2); //tile.getW();
			
			cartesians = CoordConvert.hex2Cart(u, v, w);
			x = cartesians.get(0);
			y = cartesians.get(1);
			
			for (int i = 0; i < polys.size(); i++) {
				j = i;
				if (polys.get(i).contains(x, y)) {
					u+=offset.get(0);
					v+=offset.get(1);
					w+=offset.get(2);
					
					ArrayList<Integer> offsetLocation = new ArrayList<Integer>();
					offsetLocation.add(u);
					offsetLocation.add(v);
					offsetLocation.add(w);
					
					tempName = "SECTOR" + j.toString();
					starLocations.get(tempName).add(offsetLocation);
					chosenLocations.add(offsetLocation);
					//mainTileList.add(offsetLocation);
					//coreLocations.get(tempName).add(location);
					//mainTileList.add(location);
					//removal.add(index);
				}
			}
		}
		logger.log(Level.INFO, "Finished finding sector locations");
		
		controllers = buildGenericSectors(starLocations, assetManager);
		
		return controllers;
	}
	
	
	public ArrayList<IController> buildGenericSectors(
			HashMap<String, ArrayList<ArrayList<Integer>>> locations, 
			AssetManager assetManager) {
		
		ArrayList<IController> controllers = new ArrayList<IController>();
		
		ArrayList<ArrayList<Integer>> temp;
		SectorModel sectorModel;
		HashMap<EViewList, AbstractView> sectorView;
		SectorController sectorControl;
		SectorViewBuilder sectorFact = new SectorViewBuilder();
		String name;
		
		//Set up sectors for cores, arms
		for (Map.Entry<String, ArrayList<ArrayList<Integer>>> entry : locations.entrySet()) {
			//build a sector
			temp = entry.getValue();
			name = entry.getKey();
			
			//keys.addAll(temp);
			
			sectorModel = new SectorModel(name, temp);
			sectorView = sectorFact.buildViews(assetManager);
			sectorControl = new SectorController();
			
			MVCMaker.linkElements(sectorModel, sectorView, sectorControl);
			controllers.add(sectorControl);			
		}
		
		return controllers;
		
	}
	
	

}
